
#include <BFont>
#include <BPainter>
#include <BMouseEvent>
#include <BKeyEvent>
#include <BScrollBar>
#include <BStyle>

#include "member_BSplitButton.h"
#include "member_BSplitItem.h"
#include "member_BButton.h"
#include "member_BWidget.h"
#include "member_BObject.h"

using namespace BWE;

member_BSplitButton::member_BSplitButton(BSplitButton* splitbutton)
{
	boss = splitbutton;
	arrowPart = Part_Right;
	arrowAlign = Align_Center;
	current = 0;
	exclusive = true;
	readOnly = false;

	dirty = true;

	arrow = new BButton(Graph_Arrow_Down_Fill);
	arrow->setName("arrow");
	arrow->setCheckable(true);
	arrow->setEnabled(false);
	boss->addChild(arrow);

	board = new ISplitBoard(&items, boss);
	board->setName("board");

	connect(arrow, Signal_Checked, &member_BSplitButton::slotArrowChecked);
	connect(board, Signal_Clicked, &member_BSplitButton::slotBoardClicked);
	connect(board, Signal_Styled, &member_BSplitButton::slotBoardStyled);

}
member_BSplitButton::~member_BSplitButton()
{

}

void member_BSplitButton::freshRects()
{
	arrow->setParent(boss);
	arrow->setEnabled(!readOnly);
	arrow->setVisible(arrowPart);

	BSize realArrowSize = arrowSize;
	if (realArrowSize.width() < 1)
		realArrowSize.width() = arrow->sizeHint().width();
	if (realArrowSize.height() < 1)
		realArrowSize.height() = arrow->sizeHint().height();
	arrow->setSize(realArrowSize);

	BPerch perch;
	perch.top() = boss->preferSize(Part_Top).height();
	perch.left() = boss->preferSize(Part_Left).width();
	perch.right() = boss->preferSize(Part_Right).width();
	perch.bottom() = boss->preferSize(Part_Bottom).height();

	if (arrow->visible())
	{
		if (arrowPart == Part_Top)
			perch.top() = realArrowSize.height();
		if (arrowPart == Part_Left)
			perch.left() = realArrowSize.width();
		if (arrowPart == Part_Right)
			perch.right() = realArrowSize.width();
		if (arrowPart == Part_Bottom)
			perch.bottom() = realArrowSize.height();
	}
	boss->setPerch(perch);

	if (arrow->visible())
	{
		BRect arrowArea = boss->rect(arrowPart);
		BRect arrowRect = arrowArea.align(arrowAlign, arrow->size());
		arrow->setRect(arrowRect);
	}

	if (current)
	{
		button_member(boss)->color = item_member(current)->color;
		button_member(boss)->graph = item_member(current)->graph;
		button_member(boss)->image = item_member(current)->image;
		widget_member(boss)->icon = item_member(current)->icon;
		button_member(boss)->text = item_member(current)->text;
		button_member(boss)->t_text = item_member(current)->block.text;
	}
}

void member_BSplitButton::slotArrowChecked(BObject* object, const BValue& value)
{
	board->setParent(boss);
	if (arrow->checked())
		board->popup();
	else
		board->hide();
	if (board->visible())
	{
		BRect hostRect = boss->rect();
		BRect rootRect = boss->mapFrom(boss->root(), boss->root()->size());
		BPoint offset = board->popupOffset;
		BSize size = board->sizeHint();
		if (size.width() < hostRect.width())
			size.width() = hostRect.width();
		if (size.width() > rootRect.width())
			size.width() = rootRect.width();
		int spaceUp = -rootRect.top();
		int spaceDown = rootRect.bottom() - hostRect.height();
		if (spaceDown < size.height() && spaceDown < spaceUp)
		{
			size.height() = bMin(size.height(), spaceUp);
			board->setSize(size);
			board->setPos(offset.x(), offset.y() - board->height());
		}
		else
		{
			size.height() = bMin(size.height(), spaceDown);
			board->setSize(size);
			board->setPos(offset.x(), offset.y() + hostRect.height());
		}
		boss->emit(Signal_Popup, board);
	}
}

void member_BSplitButton::slotBoardClicked(BObject* object, const BValue& value)
{
	arrow->setChecked(false);
}
void member_BSplitButton::slotBoardStyled(BObject* object, const BValue& value)
{
	dirty = true;
	boss->fresh();
}

void member_BSplitButton::slotItemColorChanged(BObject* object, const BValue& vaue)
{
	board->fresh();
	dirty = true;
	if (current == object)
	{
		object_member(boss)->emit(Signal_ColorChanged, value);
	}
	boss->fresh();
}
void member_BSplitButton::slotItemGraphChanged(BObject* object, const BValue& vaue)
{
	board->dirty = true;
	board->fresh();
	dirty = true;
	if (current == object)
	{
		object_member(boss)->emit(Signal_GraphChanged, value);
	}
	boss->fresh();
}
void member_BSplitButton::slotItemImageChanged(BObject* object, const BValue& vaue)
{
	board->dirty = true;
	board->fresh();
	dirty = true;
	if (current == object)
	{
		object_member(boss)->emit(Signal_ImageChanged, value);
	}
	boss->fresh();
}
void member_BSplitButton::slotItemIconChanged(BObject* object, const BValue& value)
{
	board->dirty = true;
	board->fresh();
	dirty = true;
	if (current == object)
	{
		object_member(boss)->emit(Signal_IconChanged, value);
	}
	boss->fresh();
}
void member_BSplitButton::slotItemValueChanged(BObject* object, const BValue& value)
{
	if (current == object)
	{
		this->value = value;
		if (boss->checks(Signal_ValueChanged))
			boss->emit(Signal_ValueChanged, value);
	}
}
void member_BSplitButton::slotItemTextChanged(BObject* object, const BValue& value)
{
	board->dirty = true;
	board->fresh();
	dirty = true;
	if (boss->checks(Signal_TextChanged))
		boss->emit(Signal_TextChanged, value);
	boss->fresh();
}
